Angular CLI Revisited

The Angular CLI can be used to create and setup Angular projects. It follows best practices and utilizes conventions to make the project easily understandable and maintainable.

To start, install the Angular CLI through NPM.

npm install -g @angular/cli

Once installed we call the CLI using the “ng” command. Create a new app as so.

ng new demo-app

A new project template is created and it has the bare essentials to start the Angular application. Run run it, use the command bellow. The application can be seen at: http://localhost:4200/

ng serve

Some other helpful quick commands:

ng doc component View Angular documentation for the ‘component’ command
ng –help Angular Help Pages
ng serve –help View options menu for the ‘serve’ command
ng serve –prod Runs the server with Angular application in production mode
ng lint Run the typescript/javascript lint analysis command
ng test Run unit tests. These found in the .spec files and has the following import:

import { TestBed, async } from '@angular/core/testing';
ng e2e Run end to end tests if any found. It does this by launching the server and running the application
ng -v Version
npm list -g @angular/cli –depth=0 List Angular CLI installation that is at the top level

 

New Applications

Some commands for creating new applications

  • ng new demo-app
  • ng new demo-app –dry-run // doesnt generate actual files, good way to see the project structure
  • ng new demo-app –skip-intall // doesnt run npm install
  • ng new –help // options
  • ng new demo-app –skip-tests –style scss –prefix demo –routing

 

When creating a new application is created the following folders and files are generated from the template.

  • e2e – end to end testing folder containing those tests
  • src – project source files
  • .angular-cli.json – configuration for angular
    • app – configuration for the app, such as folders, index file, style files, polyfill files, etc
    • app.prefix – prefix to use for all components/files created by the CLI
  • .editorconfig – configuration for how the files are to be structured
  • .gitignore – for git
  • karm.conf.js – unit testing configuration
  • package.json – npm packages
    • script – includes those script commands available for angular
    • dependencies – includes all angular packages with correct version flag (‘^5.0.1’ means any minor version thereafter; same as >=5.0 <6.0)
  • protractor.conf.js – for end to end testing
  • tsconfig.json – for typescript
  • lint.json – for linting

 

The Angular CLI could have global configurations. This is done using the ‘set’ command. Examples:

  • ng set defaults.styleExt scss -g

 

Code Blueprints

Blueprints are templated code that is to be generated. The blueprints allow options to customize the files. Blueprints are used with the ‘generate’ command. Some examples of the command are:

  • ng generate component customer
  • ng generate service customer-data
  • ng generate class customer-model

We can also use the following aliases:

  • ng g c customer
  • ng g c customer –flat true // creates component in its own folder
  • ng g c –inline-template true // (-it) creates template in the .ts file
  • ng g c –inline-style true // (-is) creates style in the .ts file
  • ng g c –spec true // create unit test spec file
  • ng g c –view-encapsulation Emulated // (-ve) view encapsulation strategy; these can be None, Emulated and Native. see below link for more details
  • ng g c –dry-run // (-d) doesnt create files
  • ng g cl -d // creates class file in dry run mode
  • ng g i myinterface // interface
  • ng g e myenum // enum
  • ng g p mypipe // pipe
  • ng g m mymodule // module – also creates a folder to put the file under

Some examples of how these generate the files:

$ ng g c orders --view-encapsulation Emulated
 CREATE src/app/orders/orders.component.html (25 bytes)
 CREATE src/app/orders/orders.component.spec.ts (628 bytes)
 CREATE src/app/orders/orders.component.ts (333 bytes)
 CREATE src/app/orders/orders.component.css (0 bytes)
 UPDATE src/app/app.module.ts (565 bytes)
$ ng g d search-box
 CREATE src/app/search-box.directive.spec.ts (237 bytes)
 CREATE src/app/search-box.directive.ts (147 bytes)
 UPDATE src/app/app.module.ts (650 bytes)
$ ng g s customer/customer-data
 CREATE src/app/customer/customer-data.service.spec.ts (411 bytes)
 CREATE src/app/customer/customer-data.service.ts (141 bytes)
$ ng g cl customer/models/customer
 CREATE src/app/customer/models/customer.ts (26 bytes)
$ ng g i customer/models/person
 CREATE src/app/customer/models/person.ts (28 bytes)
ANGULAR/CLI/demo-app]$ ng g e customer/models/gender
 CREATE src/app/customer/models/gender.enum.ts (23 bytes)
$ ng g p shared/capitalize
 CREATE src/app/shared/capitalize.pipe.spec.ts (203 bytes)
 CREATE src/app/shared/capitalize.pipe.ts (209 bytes)
 UPDATE src/app/app.module.ts (729 bytes)
$ ng g m login
CREATE src/app/login/login.module.spec.ts (267 bytes)
CREATE src/app/login/login.module.ts (189 bytes)
$ ng g c login -m login/login.module
CREATE src/app/login/login.component.html (24 bytes)
CREATE src/app/login/login.component.spec.ts (621 bytes)
CREATE src/app/login/login.component.ts (265 bytes)
CREATE src/app/login/login.component.css (0 bytes)
UPDATE src/app/login/login.module.ts (255 bytes)

The following files are generated.

// customer.ts
export class Customer {}
// gender.enum.ts
export enum Gender {}

// person.ts
export interface Person {}

// capitalize.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name:'capitalize'
})
export class CapitalizePipe implements PipeTransform {
  transform(value:any, args?:any):any {
    returnnull;
  }
}

// login.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoginComponent } from './login.component';
@NgModule({
  imports: [CommonModule],
  declarations: [LoginComponent]
})
export class LoginModule { }

// login.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
  selector:'app-login',
  templateUrl:'./login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  constructor() { }
  ngOnInit() {}
}

 

Routing

Routes need to be added to modules. A module can be created as:

  • ng g m sales --routing // creates sales module and sales-routing.module.ts

Routing is automatically added/updated by the CLI into the closest module file. In the following example we’ll create a new admin module with it’s own routing.

$ ng g m admin --routing
CREATE src/app/admin/admin-routing.module.ts (248 bytes)
CREATE src/app/admin/admin.module.spec.ts (267 bytes)
CREATE src/app/admin/admin.module.ts (275 bytes)
$ ng g c admin
CREATE src/app/admin/admin.component.html (24 bytes)
CREATE src/app/admin/admin.component.spec.ts (621 bytes)
CREATE src/app/admin/admin.component.ts (265 bytes)
CREATE src/app/admin/admin.component.css (0 bytes)
UPDATE src/app/admin/admin.module.ts (341 bytes)
$ ng g c admin/email-blast
CREATE src/app/admin/email-blast/email-blast.component.html (30 bytes)
CREATE src/app/admin/email-blast/email-blast.component.spec.ts (657 bytes)
CREATE src/app/admin/email-blast/email-blast.component.ts (288 bytes)
CREATE src/app/admin/email-blast/email-blast.component.css (0 bytes)
UPDATE src/app/admin/admin.module.ts (437 bytes)

 

Building and Serving

Using angular cli we can set build profiles for different environments. This includes running different tools for each of the profiles. For example for production we would include minification and tree-shaking when generating the final bundle files. These steps are defined in the angular.json configuration file. Some examples of the different bundle types are shown below:

  • inline.bundle.js – webpack runtime
  • main.bundle.js – app code
  • polyfills.bundle.js – polyfills
  • styles.bundle.js – styles
  • vendor.bundle.js – angular and other vendor files

 

Build environments can also have configuration files in the src folder with instructions on how to do the build. An example of the environment.prod.ts file is shown below.

export const environment = {
  production:true
};

 

The command for running the different builds are as follows:

  • ng build / ng build –target=development –environment=dev
    • environment.s
    • no cache-busting (caching images by generating different file names; aka fingerprinting)
    • css is output to js files
    • no uglification (minify and rename variables to smaller)
    • no tree-shaking (remove unused code)
    • no AOT
  • ng build –prod /// ng build –prod -e=prod
    • environment.prod.ts
    • yes cache-busting
    • css is extracted to css files
    • uglification
    • tree-shaking
    • AOT (removes angular compiler as it’s done ahead of time)
  • ng build –help

 

Some common serve commands and options:

  • ng serve –open // opens in default browser
  • ng serve –port xxxx // runs in port number
  • ng serve –live-reload (-ir) // HMR mode
  • ng serve –ssl // serve using HTTP
  • ng serve –proxy-config

 

Web-Pack / ng –reject

Angular CLI uses web-pack in the background. To see this we could use the ‘eject’ command. This will modify the package.json to show all the web-pack commands and libraries. It also creates the webpack.config.js file. When using webpack, we need to remember to use the original webpack commands, such as ‘npm start’.

 

Testing

Angular CLI has new features to support testing. This is using the ‘test’ command. By default we use Karma as the test suite. The results of the tests are automatically served through a webpage. Tests run in watch mode so any changes to the code will cause Karma to rerun the tests, which we can see on the browser as it will say ‘executing’.

Some options for ‘ng test’:

  • –code-coverage (–cc) // generates code coverage
  • –single-run (-sr) // no watching, single run only – good for CI build
  • –progress // logs to console, more verbose
  • –sourcemaps (-sm) // generates source map
  • –watch (-w) // default is true

When using code coverage it will generate a new folder ‘coverage’ at the root of the project folder. Inside there is an index.html file that when opened, it will show the code coverage for the unit tests. It detects those parts of code where there are no tests and graphically displays it on the webpage.

 

References

Angular View Encapsulation
https://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html